package xiaojian.toolkit.netty.client;

import io.netty.channel.Channel;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class HttpClientFactory implements PooledObjectFactory<HttpClient> {
    private static final Logger logger = LoggerFactory.getLogger(HttpClientFactory.class);

    private String remoteAddress;
    private int remotePort;
    private String localAddress = "0.0.0.0";
    private int localPort;

    public PooledObject<HttpClient> makeObject() throws Exception {
        HttpClient httpClient = getHttpClient();  //not singleton
        httpClient.setRemoteAddress(remoteAddress);
        httpClient.setRemotePort(remotePort);
        httpClient.setLocalAddress(localAddress);
        httpClient.setLocalPort(localPort);
        logger.debug("created a new httpClient {}", httpClient);
        return new DefaultPooledObject<HttpClient>(httpClient);
    }

    public void destroyObject(PooledObject<HttpClient> obj) throws Exception {
        logger.debug("destroy an old httpClient {}", obj);
        obj.getObject().close();
    }

    public boolean validateObject(PooledObject<HttpClient> obj) {
        Channel channel = obj.getObject().getChannel();
        return channel != null && channel.isActive();
    }

    public void activateObject(PooledObject<HttpClient> obj) throws Exception {
        obj.getObject().connect();
    }

    public void passivateObject(PooledObject<HttpClient> obj) throws Exception {
    }

    public abstract HttpClient getHttpClient();

    public String getRemoteAddress() {
        return remoteAddress;
    }

    public void setRemoteAddress(String remoteAddress) {
        this.remoteAddress = remoteAddress;
    }

    public int getRemotePort() {
        return remotePort;
    }

    public String getLocalAddress() {
        return localAddress;
    }

    public void setLocalAddress(String localAddress) {
        this.localAddress = localAddress;
    }

    public int getLocalPort() {
        return localPort;
    }

    public void setLocalPort(int localPort) {
        this.localPort = localPort;
    }

    public void setRemotePort(int remotePort) {
        this.remotePort = remotePort;
    }
}
